﻿using System;
using System.Threading;
using System.Windows.Forms;
using CosyTrade.Data;
using DevExpress.XtraBars;
using DevExpress.XtraEditors;

namespace CosyTrade.UI
{
    public partial class DetailFormBase : FormBase 
    {
        private readonly Guid objectKey;
        private BusinessObject currentObject;
        private DetailFormCurrentStat currentStat;
        private bool readOnlyMode;
        
        public DetailFormBase() : this(Guid.Empty)
        {

        }
        
        public DetailFormBase(Guid objectKey)
        {
            this.objectKey = objectKey;

            InitializeComponent();
        }

        public DetailFormBase(BusinessObject obj)
        {
            objectKey = obj.PrimaryKey;
            currentObject = obj;
            currentStat = DetailFormCurrentStat.ViewStat;

            InitializeComponent();
        }

        protected DetailFormCurrentStat CurrentStat
        {
            get { return currentStat; }
        }

        public BusinessObject CurrentObject
        {
            get { return currentObject; }
        }

        public bool ReadOnlyMode
        {
            get { return readOnlyMode; }
            set
            {
                readOnlyMode = value;
                RefreshEditStat();
            }
        }

        private System.Threading.ManualResetEvent resetEvent = new ManualResetEvent(false);
        private void DetailFormBase_Load(object sender, EventArgs e)
        {
            if (DesignMode) return;

            if (objectKey != Guid.Empty)
                if (currentObject == null)
                {
                    currentStat = DetailFormCurrentStat.ViewStat;
                    SetAllControlDisable();
                    ((ThreadStart)LoadBusinessObjectInvoke).BeginInvoke(LoadBusinessObjectAsyncCallback, null);
                }
                else InitForm();
            else InitEmptyForm();

            if (MdiParent == null)
            {
                Left = Screen.PrimaryScreen.WorkingArea.Width/2 - Width/2;
                Top = Screen.PrimaryScreen.WorkingArea.Height/2 - Height/2;
            }
            resetEvent.Set();
        }

        private void SetAllControlDisable()
        {
            btnEdit.Visibility =  BarItemVisibility.Never;
            btnSave.Visibility = BarItemVisibility.Never;
            btnCancel.Visibility = BarItemVisibility.Never;
            chkInputType.Visibility = BarItemVisibility.Never;
            btnClose.Visibility = BarItemVisibility.Always;

            foreach (Control control in Controls)
                SetControlDisable(control);
        }

        private static void SetControlDisable(Control control)
        {
            if (control is PopupContainerControl) return;

            if (!string.IsNullOrEmpty(control.Name))
            {
                control.Enabled = false;
            }

            foreach (Control control1 in control.Controls)
                SetControlDisable(control1);
        }

        private void InitForm()
        {
            Text = GetTitle();
            DataBinding();
            RefreshEditStat();
        }

        private void InitEmptyForm()
        {
            currentObject = CreateNewBusinessObject();
            currentStat = DetailFormCurrentStat.AddStat;
            Text = GetTitle() + " - 新建";
            DataBinding();
            RefreshEditStat();
        }

        private void LoadBusinessObjectInvoke()
        {
            currentObject = InitBusinessObject(objectKey);
            if (CurrentObject != null) CurrentObject.AcceptChanges();
        }

        private void LoadBusinessObjectAsyncCallback(IAsyncResult ar)
        {
            if (currentObject == null) return;
            resetEvent.WaitOne();
            Invoke((ThreadStart) InitDetailForm);
        }

        private void InitDetailForm()
        {
            currentStat = GetDefaultStat();
            Text = GetTitle();
            DataBinding();
            RefreshEditStat();
        }

        protected virtual BusinessObject InitBusinessObject(Guid currObjKey)
        {
            return null;
        }

        protected virtual BusinessObject CreateNewBusinessObject()
        {
            return null;
        }

        protected virtual string GetTitle()
        {
            return "明细信息";
        }

        protected virtual DetailFormCurrentStat GetDefaultStat()
        {
            return DetailFormCurrentStat.ViewStat;
        }

        protected virtual void DataBinding()
        {
            
        }

        protected virtual bool ControlCanEdit(Control control)
        {
            return true;
        }

        protected virtual bool ControlCanVisible(Control control)
        {
            return true;
        }

        protected virtual bool IsVail()
        {
            return true;
        }

        protected virtual void BeforeSave()
        {
            
        }

        protected virtual void Save(BusinessObject currentObj)
        {
            
        }

        protected virtual void AfterSave()
        {
            
        }

        protected virtual void AfterRefreshEditStat()
        {
            
        }

        protected virtual void CancelModifly()
        {
            
        }

        protected void BindingControl(Control control, string propertyName, string dataMember)
        {
            control.DataBindings.Clear();
            control.DataBindings.Add(propertyName, currentObject, dataMember);
        }

        protected void RefreshEditStat()
        {
            btnEdit.Visibility = currentStat == DetailFormCurrentStat.ViewStat && !ReadOnlyMode
                                     ? BarItemVisibility.Always
                                     : BarItemVisibility.Never;
            btnClose.Visibility = currentStat == DetailFormCurrentStat.ViewStat
                                     ? BarItemVisibility.Always
                                     : BarItemVisibility.Never;
            btnSave.Visibility = btnCancel.Visibility =
                                 currentStat == DetailFormCurrentStat.ViewStat
                                     ? BarItemVisibility.Never
                                     : BarItemVisibility.Always;
            chkInputType.Visibility = BarItemVisibility.Never;
            //chkInputType.Visibility = btnSave.Visibility == BarItemVisibility.Always &&
            //                          CurrentStat == DetailFormCurrentStat.AddStat 
            //                              ? BarItemVisibility.Always
            //                              : BarItemVisibility.Never;

            foreach (Control control in Controls)
                SetControlEditStat(control);

            btnEdit.Enabled = btnClose.Enabled = btnSave.Enabled = btnCancel.Enabled = true;
        }

        private void SetControlEditStat(Control control)
        {
            if (!string.IsNullOrEmpty(control.Name))
            {
                if (!(control is PopupContainerControl))
                {
                    control.Visible = ControlCanVisible(control);
                    if (!control.Visible) return;
                }
                control.Enabled = !(currentStat == DetailFormCurrentStat.ViewStat) && ControlCanEdit(control);
            }

            foreach (Control control1 in control.Controls)
                SetControlEditStat(control1);

            AfterRefreshEditStat();
        }

        private void btnEdit_ItemClick(object sender, ItemClickEventArgs e)
        {
            currentStat = DetailFormCurrentStat.EditStat;
            Text = GetTitle() + " - 编辑";
            RefreshEditStat();
        }

        private void btnClose_ItemClick(object sender, ItemClickEventArgs e)
        {
            Close();
        }

        private void btnSave_ItemClick(object sender, ItemClickEventArgs e)
        {
            Functions.SendTabKey(this);
            if (!IsVail()) return;
            using (new CursorHelper(this))
            {
                BeforeSave();
                Save(currentObject);
                AfterSave();
            }
            currentStat = DetailFormCurrentStat.ViewStat;
            RefreshEditStat();
            CurrentObject.AcceptChanges();
        }

        private void btnCancel_ItemClick(object sender, ItemClickEventArgs e)
        {
            IORM saveObj = currentObject.GetChanges();
            if (saveObj == null)
            {
                if (CurrentObject.IsNew) Close();
                else
                {
                    currentStat = DetailFormCurrentStat.ViewStat;
                    RefreshEditStat();
                    Text = GetTitle();
                }
                return;
            }

            if (Functions.ShowConfigBox("是否放弃保存数据？") != DialogResult.Yes) return;
            CancelModifly();
            if (!currentObject.IsNew)
            {
                currentObject.RejectChanges();
                currentStat = DetailFormCurrentStat.ViewStat;
                RefreshEditStat();
                Text = GetTitle();
            }
            else
            {
                currentStat = DetailFormCurrentStat.ViewStat;
                Close();
            }
        }

        private void DetailFormBase_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (CurrentStat == DetailFormCurrentStat.ViewStat) return;
            Functions.ShowMessageBox("请先退出编辑状态再关闭窗体");
            e.Cancel = true;
        }
    }

    [Flags]
    public enum DetailFormCurrentStat
    {
        AddStat,
        EditStat,
        ViewStat,
    }
}
